#-*- coding:utf-8 -*-
import struct  

# 支持文件类型  
# 用16进制字符串的目的是可以知道文件头是多少字节  
# 各种文件头的长度不一样，少半2字符，长则8字符  
def typeList():  
    return {
        "52617221":'rar',  
        "504B0304":'zip',
        "FFD8FF":'jpg',
        "89504E47":'png',
        "47494638":'gif',
        "49492A00":'tif',
        "424D":'bmp',
        "41433130":'dwg',
        "38425053":'psd',
        "7B5C727466":'rtf',
        "3C3F786D6C":'xml',
        "68746D6C3E":'html',
        #"44656C69766572792D646174653A":'eml',
        #"CFAD12FEC5FD746F":'dbx',
        #"2142444E":'pst',
        "D0CF11E0":'xls or doc',
        "5374616E64617264204A":'mdb',
        "41564920":'avi',
        "57415645":'wav',
        "000001BA":'mpg',
        "000001B3":'mpg',
        }  
  
# 字节码转16进制字符串  
def bytes2hex(bytes):  
    num = len(bytes)  
    hexstr = u""  
    for i in range(num):  
        t = u"%x" % bytes[i]  
        if len(t) % 2:  
            hexstr += u"0"  
        hexstr += t  
    return hexstr.upper()  

import os

# 获取文件类型  
def filetype(filename):  
    binfile = open(filename, 'rb') # 必需二制字读取  
    splitfile = os.path.splitext(filename)        #如果是文本文件，任何文件都可以改成文本文件，无法用二进制识别，只能分离
    tl = typeList()  
    ftype = 'unknown'  
    for hcode in tl.keys():  
        numOfBytes = len(hcode) / 2 # 需要读多少字节  
        binfile.seek(0) # 每次读取都要回到文件头，不然会一直往后读取  
        hbytes = struct.unpack_from("B"*numOfBytes, binfile.read(numOfBytes)) # 一个 "B"表示一个字节  
        f_hcode = bytes2hex(hbytes)
        print f_hcode
        if f_hcode == hcode:  
            ftype = tl[hcode]  
            break  
        elif splitfile[1] == '.txt':
            ftype = 'txt'
            break
    binfile.close()  
    return ftype  
  
if __name__ == '__main__':  
    print filetype('C:\Users\myczg\Desktop\czg.docx')  
